package com.system.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ibatis xml 转换为mybatis xml 工具
 * @Author KT_1988
 * @Date 2021/2/2 14:01
 */
public class ReplaceXml {

	private static List<String> fileNameList = new ArrayList<>();
//    private static final String FILE_PATH = "D:\\workspace\\Proc-master\\src\\com\\steel\\mapper\\proc\\xml";
    private static final String DAO_PACKAGE = "com.steel";
    private static final String FILE_PATH = "C:\\storageProject\\workspace\\Proc\\src\\com\\steel\\xml";
    public static void main(String[] args) throws Exception {
    	
    	List<String> fileList = getFile(FILE_PATH);
    	for (String nameItem : fileList) {
    		File file = new File(FILE_PATH + "\\" + nameItem);
    		cdFile(file);
		}
    }

    private static List<String> getFile(String path) {
		// 获得指定文件对象
		File file = new File(path);
		// 获得该文件夹内的所有文件
		File[] array = file.listFiles();

		for (int i = 0; i < array.length; i++) {
			if (array[i].isFile()) {
				if (array[i].getName().contains(".xml")) {					
					fileNameList.add(array[i].getName());
				}
			} else if (array[i].isDirectory()) {
				getFile(array[i].getPath());
			}
		}
		return fileNameList;
	}
    
    private static void cdFile(File file) throws Exception {
        if(file.isDirectory()){
            File[] files = file.listFiles();
            for (File f : files) {
                cdFile(f);
            }
        }else{
            doReplaceToMybatisXml(file);
        }
    }

    private static void doReplaceToMybatisXml(File file) throws Exception {
        try {
            FileInputStream fis = new FileInputStream(file);
            System.out.println("读取并转换文件---"+file.getAbsolutePath());
            BufferedReader bufReader = new BufferedReader(new InputStreamReader(fis));//数据流读取文件

            StringBuffer strBuffer = new StringBuffer();
            StringBuffer associationSb = new StringBuffer();
            StringBuffer colloctionSb = new StringBuffer();
            String empty = "";
            String tihuan = "";
            boolean replaceDynamic = false;
            String dynamicPrepend = "";
            String fileName = file.getName();
            for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {
                if(temp.contains("<typeAlias")){
                    temp="";
                }else if (temp.contains("<resultMap")) {
                        associationSb = new StringBuffer();
                        colloctionSb = new StringBuffer();
                    //转换属性
                    temp = convertAttr(temp);
                }else if (temp.contains("</resultMap>")) {
                        temp = associationSb.toString() + colloctionSb.toString() + temp;
                }else{
                    temp = convertNamespace(temp, fileName);

                    temp = temp.replace("//iBATIS.com//DTD SQL Map 2.0//EN","//mybatis.org//DTD Mapper 3.0//EN");
                    temp = temp.replace("http://ibatis.apache.org/dtd/sql-map-2.dtd","http://mybatis.org/dtd/mybatis-3-mapper.dtd");
                    temp = temp.replace("http://www.ibatis.com/dtd/sql-map-2.dtd","http://mybatis.org/dtd/mybatis-3-mapper.dtd");
                    temp = temp.replace("<dynamic>","");
                    if(replaceDynamic && temp.contains("</dynamic")){
                        temp = temp.replace("</dynamic>","</"+dynamicPrepend+">");
                        replaceDynamic=false;
                    }else{
                        temp = temp.replace("</dynamic>","");
                    }

//                    temp = convertSelectId(temp,fileName);

                    //转换结束标签
                    temp = convertEndLabel(temp);
                    //转换属性
                    temp = convertAttr(temp);
                    //jdbcType替换
                    temp = convertJdbcType(temp);


                    temp = temp.replace("nullValue=\"0\"","");
                    Matcher matcher = getMatcher("\\#(.*?)#", temp);
                    while (matcher.find()){
                        String group = matcher.group(1);
                        String target = "#"+group+"#";
                        String dir = "#{"+group+"}";
                        temp = temp.replace(target,dir);
    //                    System.out.println("temp="+temp);
                    }
                    matcher = getMatcher("\\$(.*?)\\$", temp);
                    while (matcher.find()){
                        String group = matcher.group(1);
                        String target = "$"+group+"$";
                        String dir = "${"+group+"}";
                        temp = temp.replace(target,dir);
                    }
                    if(temp.contains("<isGreaterThan")){
                        String property ="";
                        String prepend ="";
                        String compareValue ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("compareValue=\"(.*?)\"", temp);
                        while (matcher.find()){
                            compareValue = matcher.group(1);
                        }
                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }

                        temp="<if test=\""+property+" > "+compareValue+"\" > "+prepend;

                    }else if(temp.contains("<isNotNull")){
                        String property ="";
                        String prepend ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }

                        temp="<if test=\""+property+" != null\" > "+prepend;



                    }else if(temp.contains("<isNotEqual")){
                        String property ="";
                        String prepend ="";
                        String compareValue ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("compareValue=\"(.*?)\"", temp);
                        while (matcher.find()){
                            compareValue = matcher.group(1);
                        }
                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }

                        temp="<if test=\""+property+" != "+compareValue+"\" > "+prepend;

                    }else if(temp.contains("<isNotEmpty")){
                        String property ="";
                        String prepend ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }
                        // <isNotEmpty prepend=" ," property="billNo">billNo = #{billNo,jdbcType=VARCHAR}</if>
                        // <isNotEmpty prepend=" ," property="billNo">billNo= #{billNo,jdbcType=VARCHAR}</if>
                        // <isNotEmpty prepend=" ," property="billNo">BillNo= #{billNo,jdbcType=VARCHAR}</if>
                        // <isNotEmpty prepend=" ," property="billNo"> BillNo= #{billNo,jdbcType=VARCHAR}</if>
                        if (temp.contains(">")) {
                        	prepend = prepend + " " +temp.substring(temp.indexOf(">") + 1);
                        }
                        temp="<if test=\""+property+" != null\" > "+prepend;
                    }else if(temp.contains("<isEmpty")){
                        String property ="";
                        String prepend ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }

                        temp="<if test=\""+property+" == null\" > "+prepend;
                    }else if(temp.contains("<isEqual")){
                        String property ="";
                        String prepend ="";
                        String compareValue ="";
                        matcher = getMatcher("property=\"(.*?)\"", temp);
                        while (matcher.find()){
                            property = matcher.group(1);
                        }

                        matcher = getMatcher("compareValue=\"(.*?)\"", temp);
                        while (matcher.find()){
                            compareValue = matcher.group(1);
                        }
                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            prepend = matcher.group(1);
                        }

                        temp="<if test=\""+property+" == "+compareValue+"\" > "+prepend;
                    }else if(temp.contains("<iterate")){
                        temp=temp.replace("<iterate","<foreach");
                        temp=temp.replace(" property="," collection=");
                        temp=temp.replace(" conjunction="," separator=");
                    }else if(temp.contains("<dynamic")){
                        matcher = getMatcher("prepend=\"(.*?)\"", temp);
                        while (matcher.find()){
                            dynamicPrepend = matcher.group(1);
                        }
                        temp="<"+dynamicPrepend.toLowerCase()+">";
                        replaceDynamic=true;
                    }

                    if(temp.contains("<result ") && temp.contains("select=")){
                        String replacedStr = temp;
                        if(temp.contains("javaType=\"ArrayList\"")){

                            replacedStr=replacedStr.replace("javaType=\"ArrayList\"","");
                            replacedStr = replacedStr.replace("<result ","<collection ");
                            colloctionSb.append(replacedStr).append(System.getProperty("line.separator"));
                        }else{
                            replacedStr = replacedStr.replace("<result ","<association ");
                            associationSb.append(replacedStr).append(System.getProperty("line.separator"));
                        }
                        temp = "";
                    }
                }
                strBuffer.append(temp);
                strBuffer.append(System.getProperty("line.separator"));//行与行之间的分割
            }
            bufReader.close();

//            String absolutePath = file.getParentFile().getCanonicalPath();
            String absolutePath = System.getProperty("user.dir");
            System.out.println(absolutePath);
            absolutePath = absolutePath +"\\mybatisXml\\";
            File mybatisXmlDir = new File(absolutePath);
            if(!mybatisXmlDir.exists()){
                mybatisXmlDir.mkdirs();
            }
            String destFile = absolutePath+ fileName;
            System.out.println("生成mybatisXml文件---"+destFile);
            PrintWriter printWriter = new PrintWriter(destFile);//替换后输出的文件位置
            printWriter.write(strBuffer.toString().toCharArray());
            printWriter.flush();
            printWriter.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    //首字母小写
    public static String toLowerCaseFirstOne(String s){
        if(Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    //首字母转大写
    public static String toUpperCaseFirstOne(String s){
        if(Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    private static String humpString(String str) {
        String[] splitStr = str.split("-");
        StringBuffer sb = new StringBuffer();
        for (String s : splitStr) {
            s = s.toLowerCase();
            sb.append(toUpperCaseFirstOne(s));
        }
        str = sb.toString();
        return str;
    }

    private static String convertNamespace(String temp, String fileName) {
        if (temp.contains("sqlMap") || temp.contains("<mapper")){
            temp = temp.replace("sqlMap","mapper");


            String[] split = fileName.split("-");
            String nameSpace = DAO_PACKAGE+"."+split[0]+"DAO";

            temp = temp.replaceAll("namespace=\"(.*?)\"","namespace=\""+nameSpace+"\"");

        }
        return temp;
    }

    //转换属性
    private static String convertAttr(String temp) {
        temp = temp.replace(" resultClass"," resultType");

        String property ="";
        Matcher matcher = getMatcher("columnIndex=\"(.*?)\"", temp);
        while (matcher.find()){
            property = matcher.group(1);
            temp=temp.replace("columnIndex=\""+property+"\"","");
        }

        temp = temp.replace(" parameterClass="," parameterType=");
        temp = temp.replace(" class="," type=");
        return temp;
    }
    //转换结束标签
    private static String convertEndLabel(String temp) {
        temp = temp.replace("</isGreaterThan>","</if>");
        temp = temp.replace("</isNotNull>","</if>");
        temp = temp.replace("</isNotEmpty>","</if>");
        temp = temp.replace("</isNotEqual>","</if>");
        temp = temp.replace("</isEqual>","</if>");
        temp = temp.replace("</isEmpty>","</if>");
        temp = temp.replace("</iterate>","</foreach>");
        return temp;
    }

    private static String convertJdbcType(String temp) {
        temp = temp.replace("jdbcType=\"TEXT\"","jdbcType=\"VARCHAR\"");
        temp = temp.replace("jdbcType=\"MEDIUMTEXT\"","jdbcType=\"VARCHAR\"");
        temp = temp.replace("jdbcType=\"LONGTEXT\"","jdbcType=\"VARCHAR\"");

        temp = temp.replace("jdbcType=\"INT\"","jdbcType=\"INTEGER\"");
        temp = temp.replace("jdbcType=\"SMALLINT\"","jdbcType=\"INTEGER\"");
        temp = temp.replace("jdbcType=\"MEDIUMINT\"","jdbcType=\"INTEGER\"");
        temp = temp.replace("jdbcType=\"SMALLINT UNSIGNED\"","jdbcType=\"INTEGER\"");

        temp = temp.replace("jdbcType=\"NUMBER\"","jdbcType=\"LONG\"");

        temp = temp.replace("jdbcType=\"DATETIME\"","jdbcType=\"DATE\"");


        temp = temp.replace("jdbcType=\"ENUM\"","jdbcType=\"CHAR\"");
        temp = temp.replace(":VARCHAR", ",jdbcType=VARCHAR");

        return temp;
    }

    public static Matcher getMatcher(String regex, String source) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(source);
        return matcher;

    }

}

